initial commit

This commit is contained in:
2025-11-09 12:26:46 -03:00
commit fee9b9f89a
27 changed files with 669 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

10
.idea/RicoToGhostfolio.iml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (RicoToGhostfolio)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

6
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (RicoToGhostfolio)" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/RicoToGhostfolio.iml" filepath="$PROJECT_DIR$/.idea/RicoToGhostfolio.iml" />
</modules>
</component>
</project>

12
Dockerfile Normal file
View File

@@ -0,0 +1,12 @@
# Use the official Python image
FROM python:3.12-slim
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY . /code/app
CMD ["fastapi", "run", "app/main.py", "--port", "8000"]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

112
converter.py Normal file
View File

@@ -0,0 +1,112 @@
import io
import logging
import simplejson as json
import pandas as pd
import mappings
import ghostfolio_service
import datetime
from correpy.domain.enums import TransactionType
from correpy.parsers.brokerage_notes.parser_factory import ParserFactory
from fastapi import UploadFile
account_id = '1590f1bb-b3ee-4dc8-ac46-bd1f15a83e87'
logger = logging.getLogger(__name__)
def read_brokerage_pdf(file: UploadFile):
content = io.BytesIO(file.file.read())
content.seek(0)
logger.info(f'Processing {file.filename} ')
try:
brokerage_notes = ParserFactory(brokerage_note=content, password='052').parse()
return convert_to_ghostfolio(brokerage_notes, file.filename)
except Exception as e:
print(f'Failed to parse {file.filename}: {e}')
logger.error(f'Failed to parse {file.filename}: {e}')
return 500
def convert_to_ghostfolio(brokerage_list: list, filename: str):
activities = {}
for brokerage_note in brokerage_list:
reference_date = brokerage_note.reference_date.isoformat() + 'T00:00:00.000Z'
fees = (brokerage_note.settlement_fee + brokerage_note.emoluments + brokerage_note.others) / len(
brokerage_note.transactions)
# activities['meta'] = {'date': datetime.datetime.now().isoformat(), 'version': 'v0'}
activities['activities'] = []
# activities['updateCashBalance'] = 'false'
for transaction in brokerage_note.transactions:
# activity['fee'] = (brokerage_note.settlement_fee + brokerage_note.emoluments)
transaction_type: str = ''
if transaction.transaction_type == TransactionType.BUY:
transaction_type = 'BUY'
elif transaction.transaction_type == TransactionType.SELL:
transaction_type = 'SELL'
activity = {'accountId': account_id, 'comment': filename, 'date': reference_date,
'type': transaction_type,
'fee': fees, 'unitPrice': transaction.unit_price, 'quantity': transaction.amount,
'symbol': mappings.name_to_tickers[transaction.security.name.strip()].strip(),
'currency': 'BRL',
'dataSource': 'YAHOO'}
activities['activities'].append(activity)
if len(activity['symbol']) < 1:
logger.info(f'No symbol for {transaction.security.name}')
result = ghostfolio_service.import_activities(activities, filename)
return result
def read_dividends_xlsx(file: UploadFile):
dividends_xlsx = file.file
df = pd.read_excel(dividends_xlsx, engine='openpyxl')
path = f'./{file.filename}'
df.to_csv(path, encoding='utf-8')
df = pd.read_csv(path, encoding='utf-8')
df = df[df['Produto'].notnull()]
df = df[df['Tipo de Evento'] != 'PAGAMENTO DE JUROS']
return dividends_df_to_ghostfolio(df, file.filename)
def dividends_df_to_ghostfolio(dividends_df: pd.DataFrame, filename: str):
activities = {"activities": []}
for index, row in dividends_df.iterrows():
payment_date = datetime.datetime.strptime(row['Pagamento'], "%d/%m/%Y").isoformat()
name = row['Produto'].split('-')[0].strip() + '.SA'
if name in mappings.ticker_changes:
symbol = mappings.ticker_changes[name]
else:
symbol = name
activity = {
"accountId": account_id,
"date": payment_date,
"comment": filename,
"currency": "BRL",
"dataSource": "YAHOO",
"quantity": row['Quantidade'],
"type": "DIVIDEND",
"symbol": symbol,
"unitPrice": row['Preço unitário'],
"fee": 0
}
activities["activities"].append(activity)
print(activities)
return ghostfolio_service.import_activities(activities, filename)

6
docker-compose.yml Normal file
View File

@@ -0,0 +1,6 @@
services:
rico-to-ghostfolio:
ports:
- "8001:8000"
build:
dockerfile: Dockerfile

40
ghostfolio_service.py Normal file
View File

@@ -0,0 +1,40 @@
import logging
import requests
import simplejson as json
import ntfy_service
logger = logging.getLogger(__name__)
def get_bearer_token():
response = requests.post('http://192.168.1.202:3333/api/v1/auth/anonymous', data={
"accessToken": "cab07a6b0a87711013ee5457411a26c7c7dd2787830b64b914d5678d4dc54af911752975380467fd73c3798b043855520ab148a372d8fd859860703833e96cba"}
)
token = response.json()['authToken']
return token
def import_activities(activities_json, filename: str):
bearer_token = get_bearer_token()
data = json.dumps(activities_json)
response = requests.post('http://192.168.1.202:3333/api/v1/import', data=data,
headers={"Authorization": "Bearer " + bearer_token, "Content-Type": "application/json"})
print(response.json())
if len(response.json()['activities']) < 1:
logger.info(f'No activity imported for {filename}')
print(f'No activity imported for {filename}')
ntfy_service.send_notification(f'No activity imported for {filename}')
else:
ntfy_service.send_notification(f'Imported {len(response.json()['activities'])} activities from {filename}')
print(f'Imported {len(response.json()['activities'])} activities from {filename}')
# print(json.dumps(response.json(), indent=4))
return response.status_code

30
main.py Normal file
View File

@@ -0,0 +1,30 @@
import logging
from starlette.requests import Request
from starlette.responses import Response
import uvicorn
from fastapi import FastAPI, Form, UploadFile, File
import ntfy_service
from converter import read_brokerage_pdf, read_dividends_xlsx
import io
app = FastAPI()
logger = logging.getLogger(__name__)
logging.basicConfig(filename='rico-to-ghostfolio.log', level=logging.INFO)
@app.post("/brokerage")
async def convert_pdf(file: UploadFile = File(...)):
return read_brokerage_pdf(file)
@app.post("/b3dividends")
async def convert_pdf(file: UploadFile = File(...)):
return read_dividends_xlsx(file)
@app.post("/notification")
async def notification(request: Request):
message = await request.body()
return ntfy_service.send_notification(message.decode('utf8'))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)

16
mappings.py Normal file
View File

@@ -0,0 +1,16 @@
name_to_tickers = {
"BRASIL ON NM" : 'BBAS3.SA',
"BRASIL ON EJ NM": 'BBAS3.SA',
"METAL LEVE ON NM": 'LEVE3.SA',
"METAL LEVE ON ED NM": 'LEVE3.SA',
"TRAN PAULIST PN N1": 'ISAE4.SA',
"ISA ENERGIA PN N1": 'ISAE4.SA',
"TAESA PN N2": 'TAEE4.SA',
"VALE ON NM": 'VALE3.SA',
"OI ON N1": 'OIBR3.SA'
}
ticker_changes = {
"TRPL4.SA": 'ISAE4.SA',
}

3
myapp.log Normal file
View File

@@ -0,0 +1,3 @@
INFO:uvicorn.error:Started server process [14124]
INFO:uvicorn.error:Waiting for application startup.
INFO:uvicorn.error:Application startup complete.

Binary file not shown.

6
ntfy_service.py Normal file
View File

@@ -0,0 +1,6 @@
import requests
def send_notification(message: str):
response = requests.post('https://ntfy.ccalifice.com/ghostfolio', data=message, headers={"Authorization": "Bearer tk_dl5jaui6j3pc2dx9rx8qj9sdwh23k"})
return response.status_code

36
playwright_t.py Normal file
View File

@@ -0,0 +1,36 @@
from playwright.sync_api import sync_playwright
import time
with sync_playwright() as p:
# Launch a browser
browser = p.chromium.launch(headless=False) # Set headless=True if you don't want to see the browser
page = browser.new_page()
# Go to the login page
page.goto("https://www.investidor.b3.com.br/login")
# Fill in the username and password
page.fill('input[name="investidor"]', '01783945052')
page.click('button[type="submit"]')
time.sleep(2)
page.fill('input[type="password"]', 'malvado6696')
time.sleep(200)
page.click('input[type="checkbox"]')
page.click('button[type="submit"]')
# Wait for navigation or any element that confirms login success
page.wait_for_load_state('networkidle')
# Go to the protected page
page.goto("https://example.com/secret-page")
# Get the page content
content = page.content()
print(content)
# Close the browser
#browser.close()

BIN
requirements.txt Normal file

Binary file not shown.

359
rico-to-ghostfolio.log Normal file
View File

@@ -0,0 +1,359 @@
INFO:uvicorn.error:Will watch for changes in these directories: ['C:\\Users\\chris\\Documents\\Projects\\RicoToGhostfolio']
INFO:uvicorn.error:Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:uvicorn.error:Started reloader process [8348] using WatchFiles
INFO:uvicorn.error:Started server process [11176]
INFO:uvicorn.error:Waiting for application startup.
INFO:uvicorn.error:Application startup complete.
INFO:converter:Processing XPINC_NOTA_NEGOCIACAO_B3_13_10_2023.pdf
INFO:root:Parsed transaction line: 1-BOVESPA C VISTA TRAN PAULIST PN N1 200 21,85 4.370,00 D
INFO:ghostfolio_service:No activity imported for XPINC_NOTA_NEGOCIACAO_B3_13_10_2023.pdf
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:watchfiles.main:1 change detected
INFO:uvicorn.error:Shutting down
INFO:uvicorn.error:Waiting for application shutdown.
INFO:uvicorn.error:Application shutdown complete.
INFO:uvicorn.error:Finished server process [11176]
INFO:uvicorn.error:Stopping reloader process [8348]

11
test_main.http Normal file
View File

@@ -0,0 +1,11 @@
# Test your FastAPI endpoints
GET http://127.0.0.1:8000/
Accept: application/json
###
GET http://127.0.0.1:8000/hello/User
Accept: application/json
###