Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -840,41 +840,218 @@ def generate_word_document(result):
|
|
| 840 |
|
| 841 |
|
| 842 |
|
| 843 |
-
with gr.Blocks() as demo:
|
| 844 |
-
gr.Markdown("# Standardize Job Description!")
|
| 845 |
-
gr.Markdown("Identify Job Family, Occupation, Qualification, match Skills and suggest interview questions.")
|
| 846 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 847 |
with gr.Row():
|
| 848 |
with gr.Column():
|
| 849 |
file_input = gr.File(label="Upload a Post Description PDF file", file_types=[".pdf"])
|
| 850 |
-
submit_btn = gr.Button(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 851 |
|
| 852 |
with gr.Row():
|
| 853 |
with gr.Column():
|
| 854 |
-
|
| 855 |
-
responsibilities_output = gr.Textbox(label="Responsibilities", lines=5, interactive=False)
|
| 856 |
job_family_output = gr.Textbox(label="Classified Job Family", interactive=False)
|
| 857 |
-
|
| 858 |
-
|
| 859 |
with gr.Row():
|
| 860 |
with gr.Column():
|
| 861 |
gr.Markdown("## CCOG Levels")
|
| 862 |
ccoq_levels_output = gr.JSON(label="CCOG Levels")
|
| 863 |
-
|
| 864 |
-
with gr.Row():
|
| 865 |
with gr.Column():
|
| 866 |
-
gr.Markdown("##
|
| 867 |
-
|
| 868 |
-
|
| 869 |
with gr.Row():
|
| 870 |
with gr.Column():
|
| 871 |
gr.Markdown("## Skills")
|
| 872 |
skills_output = gr.JSON(label="Skills")
|
| 873 |
|
| 874 |
-
with gr.Row():
|
| 875 |
-
with gr.Column():
|
| 876 |
-
gr.Markdown("## ESCO Levels")
|
| 877 |
-
esco_levels_output = gr.JSON(label="ESCO Levels")
|
| 878 |
|
| 879 |
with gr.Row():
|
| 880 |
with gr.Column():
|
|
@@ -883,16 +1060,29 @@ with gr.Blocks() as demo:
|
|
| 883 |
|
| 884 |
with gr.Row():
|
| 885 |
with gr.Column():
|
| 886 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 887 |
|
| 888 |
if DEBUG:
|
| 889 |
with gr.Row():
|
| 890 |
with gr.Column():
|
| 891 |
-
gr.Markdown("### Debug Console")
|
| 892 |
debug_console = gr.Textbox(
|
| 893 |
-
label="",
|
| 894 |
interactive=False,
|
| 895 |
-
lines=15,
|
| 896 |
elem_classes=["debug-console"]
|
| 897 |
)
|
| 898 |
|
|
|
|
| 840 |
|
| 841 |
|
| 842 |
|
|
|
|
|
|
|
|
|
|
| 843 |
|
| 844 |
+
title="AI-powered tool to review Job Position Description",
|
| 845 |
+
css="""
|
| 846 |
+
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap');
|
| 847 |
+
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css');
|
| 848 |
+
/* Completely disable Gradio's dark theme */
|
| 849 |
+
.gradio-container.dark {
|
| 850 |
+
--body-background-fill: white !important;
|
| 851 |
+
--background-fill-primary: white !important;
|
| 852 |
+
--background-fill-secondary: #f8f9fa !important;
|
| 853 |
+
--block-background-fill: white !important;
|
| 854 |
+
--input-background-fill: white !important;
|
| 855 |
+
--block-label-text-color: #212529 !important;
|
| 856 |
+
--body-text-color: #212529 !important;
|
| 857 |
+
--block-title-text-color: var(--primary-color) !important;
|
| 858 |
+
--border-color-primary: #dee2e6 !important;
|
| 859 |
+
}
|
| 860 |
+
.gradio-container.dark .gr-markdown,
|
| 861 |
+
.gradio-container.dark .gr-textbox,
|
| 862 |
+
.gradio-container.dark .gr-dropdown,
|
| 863 |
+
.gradio-container.dark .output-section {
|
| 864 |
+
background: white !important;
|
| 865 |
+
color: #212529 !important;
|
| 866 |
+
border-color: #dee2e6 !important;
|
| 867 |
+
}
|
| 868 |
+
/* Base Styles */
|
| 869 |
+
:root {
|
| 870 |
+
--primary-color: #0033A0;
|
| 871 |
+
--secondary-color: #e67e22;
|
| 872 |
+
--accent-color: #f59e0b;
|
| 873 |
+
--dark-color: #34495e;
|
| 874 |
+
--light-color: #ecf0f1;
|
| 875 |
+
--success-color: #27ae60;
|
| 876 |
+
--warning-color: #f39c12;
|
| 877 |
+
--danger-color: #e74c3c;
|
| 878 |
+
--text-color: #333;
|
| 879 |
+
--text-light: #7f8c8d;
|
| 880 |
+
--border-radius: 8px;
|
| 881 |
+
--box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
| 882 |
+
--transition: all 0.3s ease;
|
| 883 |
+
}
|
| 884 |
+
/* Header Styles */
|
| 885 |
+
.header {
|
| 886 |
+
text-align: center;
|
| 887 |
+
margin-bottom: 2rem;
|
| 888 |
+
padding: 1rem;
|
| 889 |
+
}
|
| 890 |
+
.header h1 {
|
| 891 |
+
margin: 0;
|
| 892 |
+
font-family: 'Lato', sans-serif;
|
| 893 |
+
font-size: 2.5rem;
|
| 894 |
+
font-weight: 600;
|
| 895 |
+
color: var(--primary-color);
|
| 896 |
+
}
|
| 897 |
+
.header p {
|
| 898 |
+
margin: 0.5rem 0 0;
|
| 899 |
+
font-family: 'Lato', sans-serif;
|
| 900 |
+
opacity: 0.9;
|
| 901 |
+
font-size: 1.5rem;
|
| 902 |
+
color: #4b5563;
|
| 903 |
+
}
|
| 904 |
+
/* Section Titles */
|
| 905 |
+
.section-title {
|
| 906 |
+
display: flex;
|
| 907 |
+
align-items: left;
|
| 908 |
+
font-family: 'Lato', sans-serif;
|
| 909 |
+
gap: 0.5rem;
|
| 910 |
+
color: var(--primary-color);
|
| 911 |
+
margin: 1rem 0;
|
| 912 |
+
font-size: 1.25rem;
|
| 913 |
+
font-weight: 600;
|
| 914 |
+
}
|
| 915 |
+
.section-title i {
|
| 916 |
+
font-size: 1.1em;
|
| 917 |
+
color: var(--accent-color);
|
| 918 |
+
}
|
| 919 |
+
/* Input Section */
|
| 920 |
+
.input-section {
|
| 921 |
+
background: white;
|
| 922 |
+
padding: 0.75rem 0.5rem;
|
| 923 |
+
border: 1px solid #d1d5db;
|
| 924 |
+
border-radius: var(--border-radius);
|
| 925 |
+
box-shadow: var(--box-shadow);
|
| 926 |
+
margin-right: 1rem;
|
| 927 |
+
}
|
| 928 |
+
/* Output Section */
|
| 929 |
+
.output-section {
|
| 930 |
+
background: white;
|
| 931 |
+
padding: 1.5rem;
|
| 932 |
+
border-radius: var(--border-radius);
|
| 933 |
+
box-shadow: var(--box-shadow);
|
| 934 |
+
}
|
| 935 |
+
/* Form Elements */
|
| 936 |
+
.gr-textbox, .gr-dropdown {
|
| 937 |
+
border: 1px solid #ddd;
|
| 938 |
+
border-radius: var(--border-radius) !important;
|
| 939 |
+
padding: 0.75rem 1rem !important;
|
| 940 |
+
transition: var(--transition);
|
| 941 |
+
}
|
| 942 |
+
.gr-textbox:focus, .gr-dropdown:focus {
|
| 943 |
+
border-color: var(--primary-color) !important;
|
| 944 |
+
box-shadow: 0 0 0 2px rgba(44, 110, 203, 0.2) !important;
|
| 945 |
+
outline: none !important;
|
| 946 |
+
}
|
| 947 |
+
.gr-textbox::placeholder {
|
| 948 |
+
color: var(--text-light) !important;
|
| 949 |
+
opacity: 0.7 !important;
|
| 950 |
+
}
|
| 951 |
+
label {
|
| 952 |
+
font-weight: 500 !important;
|
| 953 |
+
color: var(--dark-color) !important;
|
| 954 |
+
margin-bottom: 0.5rem !important;
|
| 955 |
+
display: block !important;
|
| 956 |
+
}
|
| 957 |
+
/* Buttons */
|
| 958 |
+
.btn-primary {
|
| 959 |
+
background: var(--primary-color) !important;
|
| 960 |
+
color: white !important;
|
| 961 |
+
border: none !important;
|
| 962 |
+
border-radius: var(--border-radius) !important;
|
| 963 |
+
padding: 0.75rem 1.5rem !important;
|
| 964 |
+
font-weight: 500 !important;
|
| 965 |
+
transition: var(--transition) !important;
|
| 966 |
+
text-transform: uppercase !important;
|
| 967 |
+
letter-spacing: 0.5px !important;
|
| 968 |
+
}
|
| 969 |
+
.btn-primary:hover {
|
| 970 |
+
background: #002080 !important;
|
| 971 |
+
transform: translateY(-2px) !important;
|
| 972 |
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15) !important;
|
| 973 |
+
}
|
| 974 |
+
.btn-primary:active {
|
| 975 |
+
transform: translateY(0) !important;
|
| 976 |
+
}
|
| 977 |
+
/* Output Markdown */
|
| 978 |
+
.gr-markdown {
|
| 979 |
+
background: #f9f9f9;
|
| 980 |
+
padding: 1.5rem;
|
| 981 |
+
border-radius: var(--border-radius);
|
| 982 |
+
border-left: 4px solid var(--primary-color);
|
| 983 |
+
}
|
| 984 |
+
/* Debug Console */
|
| 985 |
+
.gr-textbox[label="⚠️ Console Log"] {
|
| 986 |
+
font-family: monospace !important;
|
| 987 |
+
background: #2c3e50 !important;
|
| 988 |
+
color: #ecf0f1 !important;
|
| 989 |
+
border-radius: var(--border-radius) !important;
|
| 990 |
+
padding: 1rem !important;
|
| 991 |
+
}
|
| 992 |
+
/* Responsive Layout */
|
| 993 |
+
@media (max-width: 768px) {
|
| 994 |
+
.gr-row {
|
| 995 |
+
flex-direction: column !important;
|
| 996 |
+
}
|
| 997 |
+
|
| 998 |
+
.input-section {
|
| 999 |
+
margin-right: 0 !important;
|
| 1000 |
+
margin-bottom: 1rem !important;
|
| 1001 |
+
}
|
| 1002 |
+
}
|
| 1003 |
+
""",
|
| 1004 |
+
head='''
|
| 1005 |
+
<meta name="description" content="AI-powered tool to review Job Position Description.">
|
| 1006 |
+
<meta name="keywords" content="HR, Position, Job, Skills, Qualification, Interview">
|
| 1007 |
+
<meta name="author" content="Edouard Legoupil | IOM Chief Data Officer">
|
| 1008 |
+
<link rel="author" href="https://edouard-legoupil.github.io/">
|
| 1009 |
+
<meta property="og:title" content="AI-powered tool to review Job Position Description">
|
| 1010 |
+
<meta property="og:description" content="AI-powered tool to review Job Position Description">
|
| 1011 |
+
<meta property="og:type" content="website">
|
| 1012 |
+
<link rel="icon" href="https://www.iom.int/themes/custom/phoenix/favicon.ico" type="image/vnd.microsoft.icon">
|
| 1013 |
+
<link rel="apple-touch-icon" href="https://www.iom.int/sites/g/files/tmzbdl486/files/favicon.ico">
|
| 1014 |
+
'''
|
| 1015 |
+
) as demo:
|
| 1016 |
+
|
| 1017 |
+
# Header section
|
| 1018 |
+
with gr.Column():
|
| 1019 |
+
with gr.Row():
|
| 1020 |
+
with gr.Column():
|
| 1021 |
+
gr.HTML("""
|
| 1022 |
+
<div class="header">
|
| 1023 |
+
<h1>Position Description Review (Demo)</h1>
|
| 1024 |
+
<p>Use AI to standardise an initial draft position description and identify related Job Family, Occupation, Qualification, match Skills and suggest interview questions.</p>
|
| 1025 |
+
</div>
|
| 1026 |
+
""")
|
| 1027 |
+
|
| 1028 |
with gr.Row():
|
| 1029 |
with gr.Column():
|
| 1030 |
file_input = gr.File(label="Upload a Post Description PDF file", file_types=[".pdf"])
|
| 1031 |
+
submit_btn = gr.Button(
|
| 1032 |
+
value="✨ Analyse Post Description",
|
| 1033 |
+
variant="primary",
|
| 1034 |
+
elem_classes="btn-primary"
|
| 1035 |
+
)
|
| 1036 |
|
| 1037 |
with gr.Row():
|
| 1038 |
with gr.Column():
|
| 1039 |
+
responsibilities_output = gr.Textbox(label="List of Responsibilities used for the review", lines=5, interactive=False)
|
|
|
|
| 1040 |
job_family_output = gr.Textbox(label="Classified Job Family", interactive=False)
|
| 1041 |
+
|
|
|
|
| 1042 |
with gr.Row():
|
| 1043 |
with gr.Column():
|
| 1044 |
gr.Markdown("## CCOG Levels")
|
| 1045 |
ccoq_levels_output = gr.JSON(label="CCOG Levels")
|
|
|
|
|
|
|
| 1046 |
with gr.Column():
|
| 1047 |
+
gr.Markdown("## ESCO Levels")
|
| 1048 |
+
esco_levels_output = gr.JSON(label="ESCO Levels")
|
| 1049 |
+
|
| 1050 |
with gr.Row():
|
| 1051 |
with gr.Column():
|
| 1052 |
gr.Markdown("## Skills")
|
| 1053 |
skills_output = gr.JSON(label="Skills")
|
| 1054 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1055 |
|
| 1056 |
with gr.Row():
|
| 1057 |
with gr.Column():
|
|
|
|
| 1060 |
|
| 1061 |
with gr.Row():
|
| 1062 |
with gr.Column():
|
| 1063 |
+
qualification_output = gr.Textbox(label="Qualification", lines=5, interactive=False)
|
| 1064 |
+
|
| 1065 |
+
|
| 1066 |
+
with gr.Row():
|
| 1067 |
+
with gr.Column():
|
| 1068 |
+
gr.Markdown("## Interview Questions")
|
| 1069 |
+
interview_output = gr.Textbox(label="Interview Questions", lines=10, interactive=False)
|
| 1070 |
+
|
| 1071 |
+
|
| 1072 |
+
|
| 1073 |
+
with gr.Row():
|
| 1074 |
+
with gr.Column():
|
| 1075 |
+
download_btn = gr.Button(
|
| 1076 |
+
value="📄 Download Word Document",
|
| 1077 |
+
variant="primary",
|
| 1078 |
+
elem_classes="btn-primary")
|
| 1079 |
|
| 1080 |
if DEBUG:
|
| 1081 |
with gr.Row():
|
| 1082 |
with gr.Column():
|
|
|
|
| 1083 |
debug_console = gr.Textbox(
|
| 1084 |
+
label="⚠️ Execution Log",
|
| 1085 |
interactive=False,
|
|
|
|
| 1086 |
elem_classes=["debug-console"]
|
| 1087 |
)
|
| 1088 |
|