From 72209f65cf98997311a8ebf43bf238d8c8442e98 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Fri, 3 Oct 2025 19:30:25 -0300 Subject: [PATCH 01/20] =?UTF-8?q?feat(docs):=20configurar=20GitHub=20Actio?= =?UTF-8?q?ns=20para=20publica=C3=A7=C3=A3o=20no=20GitHub=20Pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adicionado script `scripts/export_openapi.py` para exportar o schema OpenAPI - Criado workflow `.github/workflows/docs.yml` para gerar e publicar docs com Redoc - Preparado deploy automático da documentação na branch `gh-pages` --- .github/workflows/docs.yml | 48 ++ openapi.json | 1092 ++++++++++++++++++++++++++++++++++++ scripts/export_openapi.py | 24 + 3 files changed, 1164 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 openapi.json create mode 100644 scripts/export_openapi.py diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..b4a82d2 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,48 @@ +name: Deploy API Docs to GitHub Pages + +on: + push: + branches: [ main ] + workflow_dispatch: + +jobs: + build-docs: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install Python dependencies (mínimas para OpenAPI) + run: | + pip install fastapi sqlmodel sqlalchemy aiosqlite + + - name: Export OpenAPI schema + env: + SECRET_KEY: dummy + ALGORITHM: HS256 + ACCESS_TOKEN_EXPIRE_MINUTES: 20 + SQLITE_PATH: /tmp/pynewsdb.db + SQLITE_URL: sqlite+aiosqlite:////tmp/pynewsdb.db + PYTHONPATH: . + run: | + python scripts/export_openapi.py app.main:app openapi.json + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Generate static docs (Redoc) + run: | + npx --yes redoc-cli bundle openapi.json -o docs/index.html + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs \ No newline at end of file diff --git a/openapi.json b/openapi.json new file mode 100644 index 0000000..4dd5ab5 --- /dev/null +++ b/openapi.json @@ -0,0 +1,1092 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "pynews-server", + "description": "PyNews Server", + "version": "0.1.0" + }, + "paths": { + "/api/healthcheck": { + "get": { + "tags": [ + "healthcheck" + ], + "summary": "Health check endpoint", + "description": "Returns the health status of the API", + "operationId": "healthcheck_api_healthcheck_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthCheckResponse" + } + } + } + } + } + } + }, + "/api/news": { + "post": { + "tags": [ + "news" + ], + "summary": "News endpoint", + "description": "Creates news and returns a confirmation message", + "operationId": "post_news_api_news_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "user-email", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "User-Email" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/News" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewsPostResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "news" + ], + "summary": "Get News", + "description": "Retrieves news filtered by user and query params", + "operationId": "get_news_api_news_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Id" + } + }, + { + "name": "category", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Category" + } + }, + { + "name": "tags", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tags" + } + }, + { + "name": "user-email", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "User-Email" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewsGetResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/news/{news_id}/like": { + "post": { + "tags": [ + "news" + ], + "summary": "News like endpoint", + "description": "Allows user to like a news item", + "operationId": "post_like_api_news__news_id__like_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "news_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "News Id" + } + }, + { + "name": "user-email", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "User-Email" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewsLikeResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "news" + ], + "summary": "News undo like endpoint", + "description": "Allows user to undo a like to a news item", + "operationId": "delete_like_api_news__news_id__like_delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "news_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "News Id" + } + }, + { + "name": "user-email", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "User-Email" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewsLikeResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/authentication/create_commumity": { + "post": { + "tags": [ + "authentication" + ], + "summary": "Create Community", + "operationId": "create_community_api_authentication_create_commumity_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, + "/api/authentication/token": { + "post": { + "tags": [ + "authentication" + ], + "summary": "Login For Access Token", + "operationId": "login_for_access_token_api_authentication_token_post", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Body_login_for_access_token_api_authentication_token_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Token" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/authentication/me": { + "get": { + "tags": [ + "authentication" + ], + "summary": "Read Community Me", + "operationId": "read_community_me_api_authentication_me_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Community" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/api/libraries": { + "get": { + "tags": [ + "libraries" + ], + "summary": "Get libraries by language", + "description": "Get libraries by language", + "operationId": "get_by_language_api_libraries_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "language", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Language" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Library-Output" + }, + "title": "Response Get By Language Api Libraries Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "libraries" + ], + "summary": "Create a library", + "description": "Create a new library to follow", + "operationId": "create_library_api_libraries_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Library-Input" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/libraries/subscribe": { + "post": { + "tags": [ + "libraries" + ], + "summary": "Subscribe to receive library updates", + "description": "Subscribe to multiple libs and tags to receive libs updates", + "operationId": "subscribe_libraries_api_libraries_subscribe_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "user-email", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "User-Email" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Subscription" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscribeLibraryResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/libraries/request": { + "post": { + "tags": [ + "libraries" + ], + "summary": "Request a library", + "description": "Request a library to follow", + "operationId": "request_library_api_libraries_request_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "user-email", + "in": "header", + "required": true, + "schema": { + "type": "string", + "title": "User-Email" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Body_login_for_access_token_api_authentication_token_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_login_for_access_token_api_authentication_token_post" + }, + "Community": { + "properties": { + "username": { + "type": "string", + "title": "Username" + }, + "email": { + "type": "string", + "title": "Email" + } + }, + "type": "object", + "required": [ + "username", + "email" + ], + "title": "Community" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "HealthCheckResponse": { + "properties": { + "status": { + "type": "string", + "title": "Status", + "default": "healthy" + }, + "version": { + "type": "string", + "title": "Version", + "default": "2.0.0" + } + }, + "type": "object", + "title": "HealthCheckResponse" + }, + "Library-Input": { + "properties": { + "id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Id" + }, + "library_name": { + "type": "string", + "title": "Library Name" + }, + "news": { + "items": { + "$ref": "#/components/schemas/LibraryNews" + }, + "type": "array", + "title": "News" + }, + "logo": { + "type": "string", + "title": "Logo" + }, + "version": { + "type": "string", + "title": "Version" + }, + "release_date": { + "type": "string", + "format": "date", + "title": "Release Date" + }, + "releases_doc_url": { + "type": "string", + "title": "Releases Doc Url" + }, + "fixed_release_url": { + "type": "string", + "title": "Fixed Release Url" + }, + "language": { + "type": "string", + "title": "Language" + } + }, + "type": "object", + "required": [ + "library_name", + "news", + "logo", + "version", + "release_date", + "releases_doc_url", + "fixed_release_url", + "language" + ], + "title": "Library" + }, + "Library-Output": { + "properties": { + "id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Id" + }, + "library_name": { + "type": "string", + "title": "Library Name" + }, + "news": { + "items": { + "$ref": "#/components/schemas/LibraryNews" + }, + "type": "array", + "title": "News" + }, + "logo": { + "type": "string", + "title": "Logo" + }, + "version": { + "type": "string", + "title": "Version" + }, + "release_date": { + "type": "string", + "format": "date", + "title": "Release Date" + }, + "releases_doc_url": { + "type": "string", + "title": "Releases Doc Url" + }, + "fixed_release_url": { + "type": "string", + "title": "Fixed Release Url" + }, + "language": { + "type": "string", + "title": "Language" + } + }, + "type": "object", + "required": [ + "library_name", + "news", + "logo", + "version", + "release_date", + "releases_doc_url", + "fixed_release_url", + "language" + ], + "title": "Library" + }, + "LibraryNews": { + "properties": { + "tag": { + "$ref": "#/components/schemas/LibraryTagUpdatesEnum" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "tag", + "description" + ], + "title": "LibraryNews" + }, + "LibraryRequest": { + "properties": { + "library_name": { + "type": "string", + "title": "Library Name" + }, + "library_home_page": { + "type": "string", + "title": "Library Home Page" + } + }, + "type": "object", + "required": [ + "library_name", + "library_home_page" + ], + "title": "LibraryRequest" + }, + "LibraryResponse": { + "properties": { + "status": { + "type": "string", + "title": "Status", + "default": "Library created successfully" + } + }, + "type": "object", + "title": "LibraryResponse" + }, + "LibraryTagUpdatesEnum": { + "type": "string", + "enum": [ + "updates", + "bug_fix", + "new_feature", + "security_fix" + ], + "title": "LibraryTagUpdatesEnum" + }, + "News": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "content": { + "type": "string", + "title": "Content" + }, + "category": { + "type": "string", + "title": "Category" + }, + "tags": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "source_url": { + "type": "string", + "title": "Source Url" + }, + "social_media_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Social Media Url" + }, + "likes": { + "type": "integer", + "title": "Likes", + "default": 0 + } + }, + "type": "object", + "required": [ + "title", + "content", + "category", + "source_url" + ], + "title": "News" + }, + "NewsGetResponse": { + "properties": { + "status": { + "type": "string", + "title": "Status", + "default": "Lista de News Obtida" + }, + "news_list": { + "items": {}, + "type": "array", + "title": "News List", + "default": [] + } + }, + "type": "object", + "title": "NewsGetResponse" + }, + "NewsLikeResponse": { + "properties": { + "total_likes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Total Likes" + } + }, + "type": "object", + "required": [ + "total_likes" + ], + "title": "NewsLikeResponse" + }, + "NewsPostResponse": { + "properties": { + "status": { + "type": "string", + "title": "Status", + "default": "News Criada" + } + }, + "type": "object", + "title": "NewsPostResponse" + }, + "SubscribeLibraryResponse": { + "properties": { + "status": { + "type": "string", + "title": "Status", + "default": "Subscribed in libraries successfully" + } + }, + "type": "object", + "title": "SubscribeLibraryResponse" + }, + "Subscription": { + "properties": { + "tags": { + "items": { + "$ref": "#/components/schemas/LibraryTagUpdatesEnum" + }, + "type": "array", + "title": "Tags" + }, + "libraries_list": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Libraries List" + } + }, + "type": "object", + "required": [ + "tags", + "libraries_list" + ], + "title": "Subscription" + }, + "Token": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + }, + "expires_in": { + "type": "integer", + "title": "Expires In" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type", + "expires_in" + ], + "title": "Token" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "/authentication/token" + } + } + } + } + } +} \ No newline at end of file diff --git a/scripts/export_openapi.py b/scripts/export_openapi.py new file mode 100644 index 0000000..8b1728b --- /dev/null +++ b/scripts/export_openapi.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# scripts/export_openapi.py +import importlib +import json +import sys + +def load_app(dotted): + if ':' in dotted: + module_name, attr = dotted.split(':', 1) + else: + module_name, attr = dotted, 'app' + mod = importlib.import_module(module_name) + return getattr(mod, attr) + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Uso: export_openapi.py [output.json]") + sys.exit(2) + module = sys.argv[1] + out = sys.argv[2] if len(sys.argv) > 2 else "openapi.json" + app = load_app(module) + with open(out, "w") as f: + json.dump(app.openapi(), f, indent=2) + print(f"Wrote {out}") From 2fa1c48b1875f3c17d9db284bd19261a6089d1f4 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Fri, 3 Oct 2025 19:41:47 -0300 Subject: [PATCH 02/20] Feat(docs): Adicionado requirementes.txt --- requirements.txt | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a18c7d3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,39 @@ +aiosqlite==0.21.0 ; python_version >= "3.12" and python_version < "4.0" +annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "4.0" +anyio==4.9.0 ; python_version >= "3.12" and python_version < "4.0" +bcrypt==4.3.0 ; python_version >= "3.12" and python_version < "4.0" +certifi==2025.7.14 ; python_version >= "3.12" and python_version < "4.0" +cfgv==3.4.0 ; python_version >= "3.12" and python_version < "4.0" +click==8.2.1 ; python_version >= "3.12" and python_version < "4.0" +colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and platform_system == "Windows" +deprecated==1.2.18 ; python_version >= "3.12" and python_version < "4.0" +distlib==0.4.0 ; python_version >= "3.12" and python_version < "4.0" +fastapi==0.115.14 ; python_version >= "3.12" and python_version < "4.0" +filelock==3.18.0 ; python_version >= "3.12" and python_version < "4.0" +greenlet==3.2.3 ; python_version >= "3.12" and python_version < "3.14" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32") +h11==0.16.0 ; python_version >= "3.12" and python_version < "4.0" +httpcore==1.0.9 ; python_version >= "3.12" and python_version < "4.0" +httpx==0.28.1 ; python_version >= "3.12" and python_version < "4.0" +identify==2.6.12 ; python_version >= "3.12" and python_version < "4.0" +idna==3.10 ; python_version >= "3.12" and python_version < "4.0" +limits==5.5.0 ; python_version >= "3.12" and python_version < "4.0" +nodeenv==1.9.1 ; python_version >= "3.12" and python_version < "4.0" +orjson==3.10.18 ; python_version >= "3.12" and python_version < "4.0" +packaging==25.0 ; python_version >= "3.12" and python_version < "4.0" +platformdirs==4.3.8 ; python_version >= "3.12" and python_version < "4.0" +pre-commit==4.2.0 ; python_version >= "3.12" and python_version < "4.0" +pydantic-core==2.33.2 ; python_version >= "3.12" and python_version < "4.0" +pydantic==2.11.7 ; python_version >= "3.12" and python_version < "4.0" +pyjwt==2.10.1 ; python_version >= "3.12" and python_version < "4.0" +python-multipart==0.0.20 ; python_version >= "3.12" and python_version < "4.0" +pyyaml==6.0.2 ; python_version >= "3.12" and python_version < "4.0" +slowapi==0.1.9 ; python_version >= "3.12" and python_version < "4.0" +sniffio==1.3.1 ; python_version >= "3.12" and python_version < "4.0" +sqlalchemy==2.0.41 ; python_version >= "3.12" and python_version < "4.0" +sqlmodel==0.0.24 ; python_version >= "3.12" and python_version < "4.0" +starlette==0.46.2 ; python_version >= "3.12" and python_version < "4.0" +typing-extensions==4.14.1 ; python_version >= "3.12" and python_version < "4.0" +typing-inspection==0.4.1 ; python_version >= "3.12" and python_version < "4.0" +uvicorn==0.22.0 ; python_version >= "3.12" and python_version < "4.0" +virtualenv==20.32.0 ; python_version >= "3.12" and python_version < "4.0" +wrapt==1.17.3 ; python_version >= "3.12" and python_version < "4.0" From 0d127c043fdb6410d3f9dfa20b2e90abde802799 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Fri, 3 Oct 2025 19:43:33 -0300 Subject: [PATCH 03/20] Update docs.yml --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b4a82d2..868613e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -19,7 +19,7 @@ jobs: - name: Install Python dependencies (mínimas para OpenAPI) run: | - pip install fastapi sqlmodel sqlalchemy aiosqlite + pip install -r requirements.txt - name: Export OpenAPI schema env: @@ -45,4 +45,4 @@ jobs: uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs \ No newline at end of file + publish_dir: ./docs From 33ddd2e44c4ccfbda72b8eea45d6ada76dedc44a Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Fri, 3 Oct 2025 19:44:35 -0300 Subject: [PATCH 04/20] Update docs.yml --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b4a82d2..d333817 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -19,7 +19,7 @@ jobs: - name: Install Python dependencies (mínimas para OpenAPI) run: | - pip install fastapi sqlmodel sqlalchemy aiosqlite + pip install -r requirements.txt - name: Export OpenAPI schema env: From ada398a32715a1dfbaa993f72b11d9cf8c7867b8 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 22:27:05 -0300 Subject: [PATCH 05/20] =?UTF-8?q?feat(docs):=20documenta=C3=A7=C3=A3o=20au?= =?UTF-8?q?tomatizada=20com=20Sphinx,=20MyST,=20Redoc=20e=20deploy=20via?= =?UTF-8?q?=20GitHub=20Actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docs.yml | 4 ++++ docs/api.md | 7 ++++++ docs/conf.py | 45 ++++++++++++++++++++++++++++++++++++++ docs/index.md | 9 ++++++++ docs/readme.md | 5 +++++ requirements.txt | 8 +++++++ 6 files changed, 78 insertions(+) create mode 100644 docs/api.md create mode 100644 docs/conf.py create mode 100644 docs/index.md create mode 100644 docs/readme.md diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d333817..530149c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -32,6 +32,10 @@ jobs: run: | python scripts/export_openapi.py app.main:app openapi.json + - name: Export OpenAPI JSON + run: | + python scripts/export_openapi.py app.main:app openapi.json + - name: Set up Node.js uses: actions/setup-node@v4 with: diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..5ed658e --- /dev/null +++ b/docs/api.md @@ -0,0 +1,7 @@ +# API + +Abaixo está a especificação OpenAPI do PyNewsServer: + +```{redoc} +../openapi.json +``` diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..9e3042a --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,45 @@ +# -- Project information ----------------------------------------------------- +project = "pynewsserver" +author = "PyNews" + +# -- General configuration --------------------------------------------------- +extensions = [ + "myst_parser", + "sphinx_rtd_theme", + "sphinxcontrib.redoc", + "sphinx_copybutton", +] + +myst_enable_extensions = [ + "colon_fence", + "deflist", + "linkify", + "substitution", +] + +source_suffix = { + ".rst": "restructuredtext", + ".md": "markdown", +} + +master_doc = "index" + +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# -- Options for HTML output ------------------------------------------------- +html_theme = "sphinx_rtd_theme" +html_title = "Documentação - PyNewsServer" +html_static_path = ['_static'] + +# -- Options for sphinxcontrib-redoc ----------------------------------------- +redoc = [ + { + "name": "OpenAPI", + "page": "api", + "spec": "../openapi.json", + "embed": True, + "opts": { + "hide-hostname": True + } + }, +] diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..220003c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,9 @@ +# Documentação do PyNewsServer + +```{toctree} +:maxdepth: 2 +:caption: Sumário + +readme +api +``` diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 0000000..7b3b626 --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,5 @@ + + +# PyNewsServer + +[README.md no GitHub](https://github.com/PythonFloripa/PyNewsServer?tab=readme-ov-file#pynewsserver) diff --git a/requirements.txt b/requirements.txt index a18c7d3..ab404ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,11 @@ +# --- Dependências para documentação Sphinx --- +sphinx>=7.0.0 +myst-parser>=2.0.0 +sphinx-rtd-theme>=2.0.0 +sphinx-copybutton>=0.5.2 +sphinxcontrib-redoc>=1.6.0 +linkify-it-py>=2.0.0 +# --- Fim dependências documentação --- aiosqlite==0.21.0 ; python_version >= "3.12" and python_version < "4.0" annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "4.0" anyio==4.9.0 ; python_version >= "3.12" and python_version < "4.0" From a36c949326a1b27500243ef15e74d23d05e927d1 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 22:32:36 -0300 Subject: [PATCH 06/20] =?UTF-8?q?feat(docs):=20documenta=C3=A7=C3=A3o=20au?= =?UTF-8?q?tomatizada=20com=20Sphinx,=20MyST,=20Redoc=20e=20deploy=20via?= =?UTF-8?q?=20GitHub=20Actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docs.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 530149c..d333817 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -32,10 +32,6 @@ jobs: run: | python scripts/export_openapi.py app.main:app openapi.json - - name: Export OpenAPI JSON - run: | - python scripts/export_openapi.py app.main:app openapi.json - - name: Set up Node.js uses: actions/setup-node@v4 with: From e44359537fe6eec9ad4f3efa40eb92a2dcf40363 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 22:38:58 -0300 Subject: [PATCH 07/20] corrigir publish dir --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d333817..86ffe34 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -45,4 +45,4 @@ jobs: uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs \ No newline at end of file + publish_dir: ./docs/_build/html \ No newline at end of file From d0ba4e835b7d4d6fecff26ea6d2612ea921afda6 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 22:52:11 -0300 Subject: [PATCH 08/20] update docs.yml --- .github/workflows/docs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 86ffe34..7ed55a3 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,6 +12,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Disable Jekyll + run: touch docs/.nojekyll + - name: Set up Python uses: actions/setup-python@v5 with: From 57de450ab6f0babade2e76c72599613cf74f28cf Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 22:59:36 -0300 Subject: [PATCH 09/20] Update docs.yml --- .github/workflows/docs.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a3d8c59..f2939f9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,9 +12,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Disable Jekyll - run: touch docs/.nojekyll - - name: Set up Python uses: actions/setup-python@v5 with: From 2907483d2e699fcf9d34fa2ed815fa61ef6543b7 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 23:03:03 -0300 Subject: [PATCH 10/20] Update docs.yml --- .github/workflows/docs.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f2939f9..7b315f5 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -21,6 +21,11 @@ jobs: run: | pip install -r requirements.txt + + - name: Build Sphinx docs + run: | + sphinx-build -b html docs docs/_build/html + - name: Export OpenAPI schema env: SECRET_KEY: dummy From 2e99e171024ff6655a096fd8df0c0e26951d3261 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 23:05:54 -0300 Subject: [PATCH 11/20] Update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index ab404ca..540e6ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ sphinx-rtd-theme>=2.0.0 sphinx-copybutton>=0.5.2 sphinxcontrib-redoc>=1.6.0 linkify-it-py>=2.0.0 +setuptools>=68.0.0 # --- Fim dependências documentação --- aiosqlite==0.21.0 ; python_version >= "3.12" and python_version < "4.0" annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "4.0" From 11e56b29da54b1250227aee5793fd7d55baca509 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 23:09:27 -0300 Subject: [PATCH 12/20] Update requirements.txt --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 540e6ef..8118010 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -# --- Dependências para documentação Sphinx --- +# --- Dependências para actions --- sphinx>=7.0.0 myst-parser>=2.0.0 sphinx-rtd-theme>=2.0.0 @@ -6,7 +6,7 @@ sphinx-copybutton>=0.5.2 sphinxcontrib-redoc>=1.6.0 linkify-it-py>=2.0.0 setuptools>=68.0.0 -# --- Fim dependências documentação --- +# --- Fim dependências actions --- aiosqlite==0.21.0 ; python_version >= "3.12" and python_version < "4.0" annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "4.0" anyio==4.9.0 ; python_version >= "3.12" and python_version < "4.0" From a76804ba5659b06af19dc62405f0de2861c26ab7 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 23:19:11 -0300 Subject: [PATCH 13/20] adicionado o deploy pra ser pelo actions e nao pelo pages --- .github/workflows/docs.yml | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a3d8c59..e943679 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,9 +20,8 @@ jobs: with: python-version: '3.12' - - name: Install Python dependencies (mínimas para OpenAPI) - run: | - pip install -r requirements.txt + - name: Install Python dependencies + run: pip install -r requirements.txt - name: Export OpenAPI schema env: @@ -32,8 +31,7 @@ jobs: SQLITE_PATH: /tmp/pynewsdb.db SQLITE_URL: sqlite+aiosqlite:////tmp/pynewsdb.db PYTHONPATH: . - run: | - python scripts/export_openapi.py app.main:app openapi.json + run: python scripts/export_openapi.py app.main:app openapi.json - name: Set up Node.js uses: actions/setup-node@v4 @@ -41,11 +39,23 @@ jobs: node-version: '20' - name: Generate static docs (Redoc) - run: | - npx --yes redoc-cli bundle openapi.json -o docs/index.html + run: npx --yes redoc-cli bundle openapi.json -o docs/index.html - - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v4 + - name: Upload built site to Pages + uses: actions/upload-pages-artifact@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs/_build/html + path: docs + + deploy: + needs: build-docs + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 From 66709e17f722945cd8fc7ddcb2145fc6aa6a95f3 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Sat, 4 Oct 2025 23:23:54 -0300 Subject: [PATCH 14/20] Update docs.yml --- .github/workflows/docs.yml | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d995ad9..a829807 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,6 +12,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Disable Jekyll + run: touch docs/.nojekyll + - name: Set up Python uses: actions/setup-python@v5 with: @@ -20,11 +23,6 @@ jobs: - name: Install Python dependencies run: pip install -r requirements.txt - - - name: Build Sphinx docs - run: | - sphinx-build -b html docs docs/_build/html - - name: Export OpenAPI schema env: SECRET_KEY: dummy @@ -33,20 +31,15 @@ jobs: SQLITE_PATH: /tmp/pynewsdb.db SQLITE_URL: sqlite+aiosqlite:////tmp/pynewsdb.db PYTHONPATH: . - run: python scripts/export_openapi.py app.main:app openapi.json - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' + run: python scripts/export_openapi.py app.main:app docs/openapi.json - - name: Generate static docs (Redoc) - run: npx --yes redoc-cli bundle openapi.json -o docs/index.html + - name: Build Sphinx docs (com Redoc embutido) + run: sphinx-build -b html docs/ docs/_build/html - name: Upload built site to Pages uses: actions/upload-pages-artifact@v3 with: - path: docs + path: docs/_build/html deploy: needs: build-docs From 8525ae5c7c4088d53eec43f4f1c0167379e9fe5f Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Mon, 6 Oct 2025 18:59:07 -0300 Subject: [PATCH 15/20] Update index.md --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 220003c..fe518cb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,6 +4,6 @@ :maxdepth: 2 :caption: Sumário -readme +../README api ``` From 9151c5b7a186f6a7a00be5fd9d4e577601b8f9a6 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Mon, 6 Oct 2025 19:02:52 -0300 Subject: [PATCH 16/20] Update index.md --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index fe518cb..220003c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,6 +4,6 @@ :maxdepth: 2 :caption: Sumário -../README +readme api ``` From 3a18c36dbe6b14a55822bda46189548ac5e2a2d2 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Mon, 6 Oct 2025 19:04:08 -0300 Subject: [PATCH 17/20] Update docs.yml --- .github/workflows/docs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a829807..8480c64 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -36,6 +36,9 @@ jobs: - name: Build Sphinx docs (com Redoc embutido) run: sphinx-build -b html docs/ docs/_build/html + - name: Copia README.md para docs/ + run: cp README.md docs/readme.md + - name: Upload built site to Pages uses: actions/upload-pages-artifact@v3 with: From 08ae4f8607260c6bce53671e2c9c11b6795413bf Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Mon, 6 Oct 2025 19:09:00 -0300 Subject: [PATCH 18/20] Update docs.yml --- .github/workflows/docs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8480c64..396c5c0 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,6 +12,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Copia README.md para docs/ + run: cp README.md docs/readme.md + - name: Disable Jekyll run: touch docs/.nojekyll @@ -36,9 +39,6 @@ jobs: - name: Build Sphinx docs (com Redoc embutido) run: sphinx-build -b html docs/ docs/_build/html - - name: Copia README.md para docs/ - run: cp README.md docs/readme.md - - name: Upload built site to Pages uses: actions/upload-pages-artifact@v3 with: From 5469b4d56d95db3ee29fd335c52697f1228178d7 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Mon, 6 Oct 2025 19:17:58 -0300 Subject: [PATCH 19/20] Update docs.yml --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 396c5c0..f7539d5 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v4 - name: Copia README.md para docs/ - run: cp README.md docs/readme.md + run: tail -n +2 README.md >> docs/readme.md - name: Disable Jekyll run: touch docs/.nojekyll From 85cdd6ec6527171730dbc781b856dc764fad7108 Mon Sep 17 00:00:00 2001 From: Diego Espindola Date: Mon, 6 Oct 2025 19:18:47 -0300 Subject: [PATCH 20/20] Update readme.md --- docs/readme.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/readme.md b/docs/readme.md index 7b3b626..fb965e9 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,5 +1,2 @@ +# Documentação do PyNewsServer - -# PyNewsServer - -[README.md no GitHub](https://github.com/PythonFloripa/PyNewsServer?tab=readme-ov-file#pynewsserver)