Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitde9b833

Browse files
committed
python fastapi access and refresh token
0 parents  commitde9b833

20 files changed

+661
-0
lines changed

‎.env

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
DATABASE_PORT=6500
2+
POSTGRES_PASSWORD=password123
3+
POSTGRES_USER=postgres
4+
POSTGRES_DB=fastapi
5+
POSTGRES_HOST=postgres
6+
POSTGRES_HOSTNAME=127.0.0.1
7+
8+
ACCESS_TOKEN_EXPIRES_IN=15
9+
REFRESH_TOKEN_EXPIRES_IN=60
10+
JWT_ALGORITHM=RS256
11+
12+
CLIENT_ORIGIN=http://localhost:3000
13+
14+
15+
JWT_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT2dJQkFBSkJBSSs3QnZUS0FWdHVQYzEzbEFkVk94TlVmcWxzMm1SVmlQWlJyVFpjd3l4RVhVRGpNaFZuCi9KVHRsd3h2a281T0pBQ1k3dVE0T09wODdiM3NOU3ZNd2xNQ0F3RUFBUUpBYm5LaENOQ0dOSFZGaHJPQ0RCU0IKdmZ2ckRWUzVpZXAwd2h2SGlBUEdjeWV6bjd0U2RweUZ0NEU0QTNXT3VQOXhqenNjTFZyb1pzRmVMUWlqT1JhUwp3UUloQU84MWl2b21iVGhjRkltTFZPbU16Vk52TGxWTW02WE5iS3B4bGh4TlpUTmhBaUVBbWRISlpGM3haWFE0Cm15QnNCeEhLQ3JqOTF6bVFxU0E4bHUvT1ZNTDNSak1DSVFEbDJxOUdtN0lMbS85b0EyaCtXdnZabGxZUlJPR3oKT21lV2lEclR5MUxaUVFJZ2ZGYUlaUWxMU0tkWjJvdXF4MHdwOWVEejBEWklLVzVWaSt6czdMZHRDdUVDSUVGYwo3d21VZ3pPblpzbnU1clBsTDJjZldLTGhFbWwrUVFzOCtkMFBGdXlnCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t
16+
JWT_PUBLIC_KEY=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBSSs3QnZUS0FWdHVQYzEzbEFkVk94TlVmcWxzMm1SVgppUFpSclRaY3d5eEVYVURqTWhWbi9KVHRsd3h2a281T0pBQ1k3dVE0T09wODdiM3NOU3ZNd2xNQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==

‎.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__pycache__
2+
venv/
3+
# .env

‎Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
dev:
2+
docker-compose up -d
3+
4+
dev-down:
5+
docker-compose down

‎alembic.ini

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# A generic, single database configuration.
2+
3+
[alembic]
4+
# path to migration scripts
5+
script_location = alembic
6+
7+
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
8+
# Uncomment the line below if you want the files to be prepended with date and time
9+
# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
10+
# for all available tokens
11+
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
12+
13+
# sys.path path, will be prepended to sys.path if present.
14+
# defaults to the current working directory.
15+
prepend_sys_path = .
16+
17+
# timezone to use when rendering the date within the migration file
18+
# as well as the filename.
19+
# If specified, requires the python-dateutil library that can be
20+
# installed by adding `alembic[tz]` to the pip requirements
21+
# string value is passed to dateutil.tz.gettz()
22+
# leave blank for localtime
23+
# timezone =
24+
25+
# max length of characters to apply to the
26+
# "slug" field
27+
# truncate_slug_length = 40
28+
29+
# set to 'true' to run the environment during
30+
# the 'revision' command, regardless of autogenerate
31+
# revision_environment = false
32+
33+
# set to 'true' to allow .pyc and .pyo files without
34+
# a source .py file to be detected as revisions in the
35+
# versions/ directory
36+
# sourceless = false
37+
38+
# version location specification; This defaults
39+
# to alembic/versions. When using multiple version
40+
# directories, initial revisions must be specified with --version-path.
41+
# The path separator used here should be the separator specified by "version_path_separator" below.
42+
# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions
43+
44+
# version path separator; As mentioned above, this is the character used to split
45+
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
46+
# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
47+
# Valid values for version_path_separator are:
48+
#
49+
# version_path_separator = :
50+
# version_path_separator = ;
51+
# version_path_separator = space
52+
version_path_separator = os# Use os.pathsep. Default configuration used for new projects.
53+
54+
# the output encoding used when revision files
55+
# are written from script.py.mako
56+
# output_encoding = utf-8
57+
58+
sqlalchemy.url = driver://user:pass@localhost/dbname
59+
60+
61+
[post_write_hooks]
62+
# post_write_hooks defines scripts or Python functions that are run
63+
# on newly generated revision scripts. See the documentation for further
64+
# detail and examples
65+
66+
# format using "black" - use the console_scripts runner, against the "black" entrypoint
67+
# hooks = black
68+
# black.type = console_scripts
69+
# black.entrypoint = black
70+
# black.options = -l 79 REVISION_SCRIPT_FILENAME
71+
72+
# Logging configuration
73+
[loggers]
74+
keys = root,sqlalchemy,alembic
75+
76+
[handlers]
77+
keys = console
78+
79+
[formatters]
80+
keys = generic
81+
82+
[logger_root]
83+
level = WARN
84+
handlers = console
85+
qualname =
86+
87+
[logger_sqlalchemy]
88+
level = WARN
89+
handlers =
90+
qualname = sqlalchemy.engine
91+
92+
[logger_alembic]
93+
level = INFO
94+
handlers =
95+
qualname = alembic
96+
97+
[handler_console]
98+
class = StreamHandler
99+
args = (sys.stderr,)
100+
level = NOTSET
101+
formatter = generic
102+
103+
[formatter_generic]
104+
format = %(levelname)-5.5s [%(name)s] %(message)s
105+
datefmt = %H:%M:%S

‎alembic/README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Generic single-database configuration.

‎alembic/env.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
fromlogging.configimportfileConfig
2+
3+
fromsqlalchemyimportengine_from_config
4+
fromsqlalchemyimportpool
5+
6+
fromalembicimportcontext
7+
fromapp.configimportsettings
8+
fromapp.modelsimportBase
9+
10+
# this is the Alembic Config object, which provides
11+
# access to the values within the .ini file in use.
12+
config=context.config
13+
config.set_main_option(
14+
"sqlalchemy.url",f"postgresql+psycopg2://{settings.POSTGRES_USER}:{settings.POSTGRES_PASSWORD}@{settings.POSTGRES_HOSTNAME}:{settings.DATABASE_PORT}/{settings.POSTGRES_DB}")
15+
16+
# Interpret the config file for Python logging.
17+
# This line sets up loggers basically.
18+
ifconfig.config_file_nameisnotNone:
19+
fileConfig(config.config_file_name)
20+
21+
# add your model's MetaData object here
22+
# for 'autogenerate' support
23+
# from myapp import mymodel
24+
# target_metadata = mymodel.Base.metadata
25+
target_metadata=Base.metadata
26+
27+
# other values from the config, defined by the needs of env.py,
28+
# can be acquired:
29+
# my_important_option = config.get_main_option("my_important_option")
30+
# ... etc.
31+
32+
33+
defrun_migrations_offline()->None:
34+
"""Run migrations in 'offline' mode.
35+
36+
This configures the context with just a URL
37+
and not an Engine, though an Engine is acceptable
38+
here as well. By skipping the Engine creation
39+
we don't even need a DBAPI to be available.
40+
41+
Calls to context.execute() here emit the given string to the
42+
script output.
43+
44+
"""
45+
url=config.get_main_option("sqlalchemy.url")
46+
context.configure(
47+
url=url,
48+
target_metadata=target_metadata,
49+
literal_binds=True,
50+
dialect_opts={"paramstyle":"named"},
51+
)
52+
53+
withcontext.begin_transaction():
54+
context.run_migrations()
55+
56+
57+
defrun_migrations_online()->None:
58+
"""Run migrations in 'online' mode.
59+
60+
In this scenario we need to create an Engine
61+
and associate a connection with the context.
62+
63+
"""
64+
connectable=engine_from_config(
65+
config.get_section(config.config_ini_section),
66+
prefix="sqlalchemy.",
67+
poolclass=pool.NullPool,
68+
)
69+
70+
withconnectable.connect()asconnection:
71+
context.configure(
72+
connection=connection,target_metadata=target_metadata
73+
)
74+
75+
withcontext.begin_transaction():
76+
context.run_migrations()
77+
78+
79+
ifcontext.is_offline_mode():
80+
run_migrations_offline()
81+
else:
82+
run_migrations_online()

‎alembic/script.py.mako

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""${message}
2+
3+
Revision ID:${up_revision}
4+
Revises:${down_revision| comma,n}
5+
Create Date:${create_date}
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
${importsif importselse""}
11+
12+
# revision identifiers, used by Alembic.
13+
revision =${repr(up_revision)}
14+
down_revision =${repr(down_revision)}
15+
branch_labels =${repr(branch_labels)}
16+
depends_on =${repr(depends_on)}
17+
18+
19+
def upgrade() -> None:
20+
${upgradesif upgradeselse"pass"}
21+
22+
23+
def downgrade() -> None:
24+
${downgradesif downgradeselse"pass"}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""created_users_table
2+
3+
Revision ID: 15770e820938
4+
Revises:
5+
Create Date: 2022-07-06 15:11:26.439123
6+
7+
"""
8+
fromalembicimportop
9+
importsqlalchemyassa
10+
fromsqlalchemy.dialectsimportpostgresql
11+
12+
# revision identifiers, used by Alembic.
13+
revision='15770e820938'
14+
down_revision=None
15+
branch_labels=None
16+
depends_on=None
17+
18+
19+
defupgrade()->None:
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.create_table('users',
22+
sa.Column('id',postgresql.UUID(),server_default=sa.text('uuid_generate_v4()'),nullable=False),
23+
sa.Column('name',sa.String(),nullable=False),
24+
sa.Column('email',sa.String(),nullable=False),
25+
sa.Column('password',sa.String(),nullable=False),
26+
sa.Column('photo',sa.String(),nullable=True),
27+
sa.Column('verified',sa.Boolean(),server_default='False',nullable=False),
28+
sa.Column('role',sa.String(),server_default='user',nullable=False),
29+
sa.Column('created_at',sa.TIMESTAMP(timezone=True),server_default=sa.text('now()'),nullable=False),
30+
sa.Column('updated_at',sa.TIMESTAMP(timezone=True),server_default=sa.text('now()'),nullable=False),
31+
sa.PrimaryKeyConstraint('id'),
32+
sa.UniqueConstraint('email')
33+
)
34+
# ### end Alembic commands ###
35+
36+
37+
defdowngrade()->None:
38+
# ### commands auto generated by Alembic - please adjust! ###
39+
op.drop_table('users')
40+
# ### end Alembic commands ###

‎app/__init__.py

Whitespace-only changes.

‎app/config.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
frompydanticimportBaseSettings,EmailStr
2+
3+
4+
classSettings(BaseSettings):
5+
DATABASE_PORT:int
6+
POSTGRES_PASSWORD:str
7+
POSTGRES_USER:str
8+
POSTGRES_DB:str
9+
POSTGRES_HOST:str
10+
POSTGRES_HOSTNAME:str
11+
12+
JWT_PUBLIC_KEY:str
13+
JWT_PRIVATE_KEY:str
14+
REFRESH_TOKEN_EXPIRES_IN:int
15+
ACCESS_TOKEN_EXPIRES_IN:int
16+
JWT_ALGORITHM:str
17+
18+
CLIENT_ORIGIN:str
19+
20+
classConfig:
21+
env_file='./.env'
22+
23+
24+
settings=Settings()

‎app/database.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
fromsqlalchemyimportcreate_engine
2+
fromsqlalchemy.ext.declarativeimportdeclarative_base
3+
fromsqlalchemy.ormimportsessionmaker
4+
from .configimportsettings
5+
6+
SQLALCHEMY_DATABASE_URL=f"postgresql://{settings.POSTGRES_USER}:{settings.POSTGRES_PASSWORD}@{settings.POSTGRES_HOSTNAME}:{settings.DATABASE_PORT}/{settings.POSTGRES_DB}"
7+
8+
engine=create_engine(
9+
SQLALCHEMY_DATABASE_URL
10+
)
11+
SessionLocal=sessionmaker(autocommit=False,autoflush=False,bind=engine)
12+
13+
Base=declarative_base()
14+
15+
16+
defget_db():
17+
db=SessionLocal()
18+
try:
19+
yielddb
20+
finally:
21+
db.close()

‎app/main.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
fromfastapiimportFastAPI
2+
fromfastapi.middleware.corsimportCORSMiddleware
3+
fromapp.configimportsettings
4+
fromapp.routersimportuser,auth
5+
6+
app=FastAPI()
7+
8+
origins= [
9+
settings.CLIENT_ORIGIN,
10+
]
11+
12+
app.add_middleware(
13+
CORSMiddleware,
14+
allow_origins=origins,
15+
allow_credentials=True,
16+
allow_methods=["*"],
17+
allow_headers=["*"],
18+
)
19+
20+
21+
app.include_router(auth.router,tags=['Auth'],prefix='/api/auth')
22+
app.include_router(user.router,tags=['Users'],prefix='/api/users')
23+
24+
25+
@app.get('/api/healthchecker')
26+
defroot():
27+
return {'message':'Hello World'}

‎app/models.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
fromuuidimportUUID
2+
from .databaseimportBase
3+
fromsqlalchemyimportTIMESTAMP,Column,String,Boolean,text
4+
fromsqlalchemy.dialects.postgresqlimportUUID
5+
6+
7+
classUser(Base):
8+
__tablename__='users'
9+
id=Column(UUID,primary_key=True,nullable=False,
10+
server_default=text("uuid_generate_v4()"))
11+
name=Column(String,nullable=False)
12+
email=Column(String,unique=True,nullable=False)
13+
password=Column(String,nullable=False)
14+
photo=Column(String,nullable=True)
15+
verified=Column(Boolean,nullable=False,server_default='False')
16+
role=Column(String,server_default='user',nullable=False)
17+
created_at=Column(TIMESTAMP(timezone=True),
18+
nullable=False,server_default=text("now()"))
19+
updated_at=Column(TIMESTAMP(timezone=True),
20+
nullable=False,server_default=text("now()"))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp